package com.iuhao.web.test2;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

/**
 * Created by yanhao on 2017/12/25.
 */
public class TestExecutor {

    public static void main(String[] args) {

        /***

         （1）newCachedThreadPool ：创建一个可缓存线程池，如果线程池长度超过处理需要，可灵活回收空闲线程，若无可回收，则新建线程。
         （2）newFixedThreadPool：创建一个固定数目的、可重用的线程池。
         （3）newScheduledThreadPool:创建一个定长线程池，支持定时及周期性任务执行。
         （4）newSingleThreadExecutor：创建一个单线程化的线程池，它只会用唯一的工作线程来执行任务，保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
         （5）newSingleThreadScheduledExcutor：创建一个单例线程池，定期或延时执行任务。
         （6）newWorkStealingPool:创建持有足够线程的线程池来支持给定的并行级别，并通过使用多个队列，减少竞争，它需要穿一个并行级别的参数，如果不传，则被设定为默认的CPU数量。
          (7) ForkJoinPool：支持大任务分解成小任务的线程池，这是Java8新增线程池，通常配合ForkJoinTask接口的子类RecursiveAction或RecursiveTask使用。

         */


        try {
            //executor1();

            //executors2();
            //callable1();

            callables1();



        } catch (Exception e) {

        }
    }

    private static void callables1() throws InterruptedException {
        ExecutorService executor = Executors.newWorkStealingPool();
        List<Callable<String>> callables = Arrays.asList(
                () -> "task1",
                () -> "task2",
                () -> "task3");
        executor.invokeAll(callables)
                .stream()
                .map(future -> {
                    try {
                        return future.get();
                    }
                    catch (Exception e) {
                        throw new IllegalStateException(e);
                    }
                })
                .forEach(System.out::println);
    }

    private static void callable1() {
        try {
            Callable<Integer> task = () -> {
                try {
                    TimeUnit.SECONDS.sleep(1);
                    //执行完回调
                    return 123;
                }
                catch (InterruptedException e) {
                    throw new IllegalStateException("task interrupted", e);
                }
            };
            /**
             Callbale也可以像runnbales一样提交给 executor services。但是callables的结果怎
             么办？因为 submit() 不会等待任务完成，executor service不能直接返回callable
             的结果。不过，executor 可以返回一个 Future 类型的结果，它可以用来在稍后某
             个时间取出实际的结果。
             */

            ExecutorService executor = Executors.newFixedThreadPool(1);//可变线程池
            Future<Integer> future = executor.submit(task);
            System.out.println("future done? " + future.isDone());
            Integer result = future.get();
            System.out.println("future done? " + future.isDone());
            System.out.print("result: " + result);


        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    private static void executors2() {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        try {
            System.out.println("attempt to shutdown executor");
            executor.shutdown();
            executor.awaitTermination(5, TimeUnit.SECONDS);
        }
        catch (InterruptedException e) {
            System.err.println("tasks interrupted");
        } finally {
            if (!executor.isTerminated()) {
                System.err.println("cancel non-finished tasks");
            }
            executor.shutdownNow();
            System.out.println("shutdown finished");
        }
    }

    private static void executor1() {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.submit(() -> {
            String threadName = Thread.currentThread().getName();
            System.out.println("Hello " + threadName);
            executor.shutdown();//关闭线程
        });
    }
}
